
import { getPlotInfoById,nearestDevice,equipmentData } from "@/public/request/http";
import bus from '@/utils/bus'
import { ElMessage, ElNotification } from "element-plus";
import { getCropColor, calculateCenter } from "@/utils/common";
import axios from "axios";
import storage from '@/store'
const T = window.T
const boleJson = require("@/assets/json/bole.json")
const boleTownJson = require("@/assets/json/boleTown.json")
let map = null;
let zoom = 10;
let wmsLayer = null
let wmsName = null
let wmsBaseUrl = null
let polygons = []
let lines = []
let menu = null
const txtMenuItem = [
  {
    text: "放大",
    callback: function () {
      map.zoomIn();
    },
  },
  {
    text: "缩小",
    callback: function () {
      map.zoomOut();
    },
  },
  {
    text: "放置到最大级",
    callback: function () {
      map.setZoom(18);
    },
  },
  {
    text: "查看全国",
    callback: function () {
      map.setZoom(4);
    },
  },
  {
    text: "获取点击坐标",
    callback: function (lnglat) {
      alert(`坐标经纬度：${lnglat.getLng() + "," + lnglat.getLat()}`)
    }
  }
]

// 初始化地图
const init = () => {
  //初始化地图对象e
  map = new T.Map("mapContainer");
  setMapType(storage.state.mapType)
  let LngLat = boleJson.features[0].properties.center;
  //设置显示地图的中心点和级别
  map.centerAndZoom(new T.LngLat(LngLat[0], LngLat[1]), zoom);
  //允许鼠标滚轮缩放地图
  map.enableScrollWheelZoom();
  map.addEventListener("click", async (e) => {
    if (wmsLayer && wmsName == 'result') {
      let bbox = calculateBoundingBox(e.lnglat.lng, e.lnglat.lat)
      axios.get(`${wmsBaseUrl}?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetFeatureInfo&FORMAT=image/png&TRANSPARENT=true&QUERY_LAYERS=${wmsName}&STYLES&LAYERS=${wmsName}&exceptions=application/vnd.ogc.se_inimage&INFO_FORMAT=text/html&FEATURE_COUNT=50&X=50&Y=50&SRS=EPSG:4326&WIDTH=101&HEIGHT=101&BBOX=${bbox}`).then(res => {
        let data = getFeatureInfo(res.data)
        if(data){
          data.point = {}
          data.point.lng = e.lnglat.lng
          data.point.lat = e.lnglat.lat
          openPolygonWindow(data,'作物分布')
        }
      }).catch(err => {
        console.log(err);
      })
    }
  })
  addMenu()
}

const setMapType = (val=0)=> {
  let type = ''
  switch(val){
    case '0':
      type = TMAP_NORMAL_MAP //TMAP_NORMAL_MAP 正常
      break;
    case '1':
      type = TMAP_SATELLITE_MAP //TMAP_SATELLITE_MAP 卫星
      break;
    case '2':
      type = TMAP_HYBRID_MAP //TMAP_HYBRID_MAP 卫星混合
      break;
    case '3':
      type = TMAP_TERRAIN_MAP //TMAP_TERRAIN_MAP 地形
      break;
    case '4':
      type = TMAP_TERRAIN_HYBRID_MAP //TMAP_TERRAIN_HYBRID_MAP 地形混合
      break;
    default :
      break;
  }
  map.setMapType(type)
}

const calculateBoundingBox = (lng, lat) => {
  const buffer = 0.001; // 适当的缓冲距离
  const minx = lng - buffer;
  const miny = lat - buffer;
  const maxx = lng + buffer;
  const maxy = lat + buffer;
  return `${minx},${miny},${maxx},${maxy}`;
}

const getFeatureInfo = (htmlString) => {
  const parser = new DOMParser();
  const doc = parser.parseFromString(htmlString, "text/html");
  const table = doc.querySelector("table.featureInfo"); // 获取表格元素
  if(!table) return null
  const rows = table.querySelectorAll("tr"); // 获取所有行
  const keyValuePairs = {}; // 存储键值对
  // 获取表头行的属性名
  const headerRow = rows[0];
  const headerCells = headerRow.querySelectorAll("th");
  // 遍历每一行，跳过表头行（索引0）
  for (let i = 1; i < rows.length; i++) {
    const row = rows[i];
    const cells = row.querySelectorAll("td"); // 获取行中的单元格
    // 遍历每个单元格，使用表头单元格的内容作为键
    for (let j = 0; j < headerCells.length; j++) {
      const attributeName = headerCells[j].textContent;
      const cellValue = cells[j].textContent;
      keyValuePairs[attributeName] = cellValue;
    }
  }
  return keyValuePairs
}

const mapMoveTo = (point, zoom) => {
  map.panTo(new T.LngLat(point.lng, point.lat))
  if (zoom) {
    setTimeout(() => {
      map.setZoom(zoom)
    }, 200);
  }
}

const drawBoleLine = (color) => {
  lines.forEach(item=>{
    map.removeOverLay(item)
  })
  lines = []
  boleTownJson.features.forEach(item => {
    item.geometry.coordinates.forEach((item1)=>{
      item1.forEach(item2=>{
        drawLine({
          color: color?color:storage.state.coverageData.boundary.color,
          weight: storage.state.coverageData.boundary.weight,
          opacity: 1,
          lineStyle: "line",
          fillColor: "transprent",
          fillOpacity: 0,
          lines: item2
        })
      })
    })
  })
}

const mapReSet = () => {
  if (map) {
    mapClear()
    drawBoleLine();
  }
}

const mapClear = () => {
  map.clearOverLays();
  polygons = []
  if (wmsLayer) {
    map.removeLayer(wmsLayer);
    wmsLayer = null
    wmsName = null
    wmsBaseUrl = null
  }
}

const mapClearPolygons = () => {
  polygons.forEach(item => {
    map.removeOverLay(item)
  })

}

//行政区划描边
const drawLine = (data) => {
  let points = [];
  let style = {
    color: data.color,
    weight: data.weight,
    opacity: data.opacity,
    lineStyle: data.lineStyle,
    fillColor: data.fillColor,
    fillOpacity: data.fillOpacity,
  };
  data.lines.forEach((line) => {
    var point = new T.LngLat(line[0], line[1]);
    points.push(point);
  });
  var poly = new T.Polygon(points, style);
  lines.push(poly)
  map.addOverLay(poly);
};

//添加右键菜单
const addMenu = () => {
  menu = new T.ContextMenu({ width: 140 });
  for (var i = 0; i < txtMenuItem.length; i++) {
    //添加菜单项
    var item = new T.MenuItem(
      txtMenuItem[i].text,
      txtMenuItem[i].callback
    );
    menu.addItem(item);
  }
  map.addContextMenu(menu);
};

const addDeviceMenu = () =>{
  let data = {
    text: "查看附近设备信息",
    callback: function (lnglat) {
      getNearestDevice(lnglat.getLng(),lnglat.getLat())
    }
  }
  var menuItem = new T.MenuItem(
    data.text,
    data.callback
  );
  menu.addItem(menuItem);
}

const getNearestDevice = async (lng,lat)=> {
  try {
    let res = await nearestDevice({lon:lng,lat:lat });
    bus.emit('nearestDevice', res)
  } catch (error) {
    console.log(error);
    ElMessage.error("获取附近设备信息失败");
  }
}

const clearContextMenus = () => {
  menu.removeItem(menu.getItems()[5])
}

//绘制地块多边形
const drawArea = async (data, click = false) => {
  let points = [];
  if (!data.pointList) return
  data.pointList.forEach((item) => {
    points.push(new T.LngLat(item.lng, item.lat));
  });
  //创建面对象
  let polygon = new T.Polygon(points, {
    data: data,
    color: data.color,
    weight: 2,
    opacity: 1,
    fillColor: data.fillColor,
    fillOpacity: data.fillOpacity ? data.fillOpacity : 1,
  });
  //向地图上添加面
  polygon.addEventListener("click", async () => {
    if (data.type == '投入品') {
      bus.emit('showMapPop', {
        T: T,
        map: map,
        point: new T.LngLat(data.point.lng, data.point.lat),
        data: data,
        pop: 'popWindows3'
      })
    } else if (data.type == '气象') {
      console.log('1111');
      bus.emit('showPolygonPop', {
        polygon: polygon,
        T: T,
        data: data,
        pop: 'popWindows8'
      })
    } else if (data.type == '土壤') {
      bus.emit('showPolygonPop', {
        polygon: polygon,
        T: T,
        data: data,
        pop: 'popWindows9'
      })
    }  else if (data.type == '作物分布') {
      bus.emit('showPolygonPop', {
        polygon: polygon,
        T: T,
        data: data,
        pop: 'popWindows6'
      })
    }else {
      try {
        let res = await getPlotInfoById({ plotId: data.id });
        bus.emit('showPolygonPop', {
          polygon: polygon,
          T: T,
          data: res,
          pop: 'popWindows1'
        })
        bus.emit('getPlotId', {
          id: data.id
        })
      } catch (error) {
        ElMessage.error("获取地块信息失败");
      }
    }

  });
  if (click) {
    try {
      let res = await getPlotInfoById({ plotId: data.id });
      setTimeout(() => {
        bus.emit('showPolygonPop', {
          polygon: polygon,
          T: T,
          data: res,
          pop: 'popWindows1'
        })
        bus.emit('getPlotId', {
          id: data.id
        })
      }, 500);
    } catch (error) {
      console.log(error);
      ElMessage.error("获取地块信息失败");
    }
  }
  if (data.sign == 1) {
    let center = calculateCenter(data.pointList)
    drawMark(center.lng, center.lat)
  }
  map.addOverLay(polygon);
  polygons.push(polygon)
};


//获取草场确权数据
const getGrassData = (data) => {
  map.clearOverLays();
  let arr = [];
  data.features.forEach((item) => {
    arr.push({
      village: item.properties["嘎查村"],
      count: item.properties["人口数"],
      contract: item.properties["合同编"],
      address: item.properties["家庭住"],
      town: item.properties["苏木镇"],
      owner: item.properties["户主姓"],
      type: item.properties["承包类"],
      contractTime: item.properties["承包起"],
      area: item.properties["面积"],
      group: item.properties["组社"],
      phone: item.properties["联系电"],
      points: item.geometry.coordinates[0],
      // color: getColorByTown(item.properties["苏木镇"]).color,
      fillColor: "transprent",
      click: true
    });
  });
  arr.forEach((item) => {
    drawAreaPlot(item);
  });
};

//添加确权/作物地块多边形
const drawAreaPlot = (data) => {
  let points = [];
  if (data.points) {
    data.points.forEach((item) => {
      points.push(new T.LngLat(item[0], item[1]));
    })
  }
  //创建面对象
  let polygon = new T.Polygon(points, {
    data: data,
    color: data.color,
    weight: 1,
    opacity: 1,
    fillColor: data.fillColor,
    fillOpacity: 0,
  });
  if (data.click) {
    //向地图上添加面
    polygon.addEventListener("click", async () => {
      bus.emit('showPolygonPop', {
        polygon: polygon,
        T: T,
        data: data,
        pop: 'popWindows2'
      })
    });
  }
  map.addOverLay(polygon);
};

const openPolygonWindow = (data, type) => {
  if (type == '确权') {
    bus.emit('showMapPop', {
      T: T,
      map: map,
      point: new T.LngLat(data.point.lng, data.point.lat),
      data: data,
      pop: 'popWindows2'
    })
  } else if(type == '投入品') {
    bus.emit('showMapPop', {
      T: T,
      map: map,
      point: new T.LngLat(data.point.lng, data.point.lat),
      data: data,
      pop: 'popWindows3'
    })
  } else{
    bus.emit('showMapPop', {
      T: T,
      map: map,
      point: new T.LngLat(data.point.lng, data.point.lat),
      data: data,
      pop: 'popWindows6'
    })
  }
}

//添加图片标注
const drawMark = (lng, lat, url,data={}) => {
  var icon = new T.Icon({
    iconUrl: url,
    iconSize: new T.Point(30, 36),
    iconAnchor: new T.Point(10, 20)
  });
  //向地图上添加自定义标注
  var marker = new T.Marker(new T.LngLat(lng, lat), { icon: icon });
  marker.addEventListener("click", async () => {
    if (data.devieceType && data.devieceType == 'device') {
      try {
        let res = await equipmentData({ equipmentId: data.id });
        data.list = res.data
        bus.emit('showMapPop', {
          T: T,
          map: map,
          point: new T.LngLat(lng, lat),
          data: data,
          pop: data.mapPop
        })
      } catch (error) {
        console.log(error);
        ElMessage.error("获取设备信息失败");
      }
    }else{
      bus.emit('showMapPop', {
        T: T,
        map: map,
        point: new T.LngLat(lng, lat),
        data: data,
        pop: data.mapPop
      })
    }
    
  });
  map.addOverLay(marker);
};

const CropUpdate = (val) => {
  ElNotification({
    title: '地块数据更新',
    message: '',
    type: 'success',
    position: 'bottom-right',
  })
  val.pointList = val.points
  val.color = getCropColor(val.plantType).color
  val.fillColor = getCropColor(val.plantType).fillColor
  drawArea(val, true)
  map.panTo(new T.LngLat(val.lng, val.lat), 16);
};
bus.on("CropUpdate", CropUpdate);

const removeBus = () => {
  bus.off("CropUpdate", CropUpdate);
}

const addWmsLayer = (url, layer) => {
  if (wmsLayer) {
    map.removeLayer(wmsLayer);
  }
  wmsName = layer
  wmsBaseUrl = url
  wmsLayer = new T.TileLayer.WMS(url, {
    layers: layer,
    format: 'image/png',
    service: 'WMS',
    transparent: 'true',
    VERSION: "1.1.1",
    request: 'GetMap',
    srs: 'EPSG:4326'
  })
  map.addOverLay(wmsLayer);
}

export default {
  init,
  addMenu,
  drawAreaPlot,
  getGrassData,
  mapReSet,
  mapClear,
  drawArea,
  removeBus,
  mapMoveTo,
  openPolygonWindow,
  addWmsLayer,
  mapClearPolygons,
  drawMark,
  setMapType,
  drawBoleLine,
  addDeviceMenu,
  clearContextMenus,
}

